/**
 * 战斗解析器
 * 负责处理具体的战斗行动、伤害计算、技能效果等核心战斗逻辑
 */

import { 
    BattleContext, 
    BattleParticipant, 
    BattleAction, 
    BattleEffect, 
    SkillUseResult,
    DamageCalculationResult,
    HealingCalculationResult
} from './types';
import { ServiceLogger } from '../../../infrastructure/logging/UnifiedLogger';
import { BattleStateManager } from './BattleStateManager';

/**
 * 目标选择策略
 */
export enum TargetSelectionStrategy {
    RANDOM = 'random',
    LOWEST_HP = 'lowest_hp',
    HIGHEST_HP = 'highest_hp',
    LOWEST_HP_PERCENT = 'lowest_hp_percent',
    HIGHEST_THREAT = 'highest_threat'
}

/**
 * 战斗解析器
 */
export class CombatResolver {
    private logger: ServiceLogger;

    constructor() {
        this.logger = new ServiceLogger('CombatResolver');
    }

    /**
     * 处理单位行动
     */
    async processUnitAction(
        context: BattleContext,
        actor: BattleParticipant,
        enemies: BattleParticipant[],
        allies: BattleParticipant[]
    ): Promise<BattleContext> {
        if (!actor.isAlive) {
            return context;
        }

        const aliveEnemies = enemies.filter(e => e.isAlive);
        if (aliveEnemies.length === 0) {
            return context;
        }

        this.logger.debug(`Processing action for ${actor.name}`, {
            metadata: { 
                battleId: context.state.battleId,
                actorId: actor.id,
                enemiesCount: aliveEnemies.length
            }
        });

        try {
            // 选择行动类型（攻击、技能、防御等）
            const actionType = this.selectActionType(actor, aliveEnemies, allies);
            
            // 选择目标
            const targets = this.selectTargets(actor, aliveEnemies, allies, actionType);
            
            // 执行行动
            const updatedContext = await this.executeAction(context, actor, targets, actionType);
            
            // 触发行动后效果
            return await this.triggerPostActionEffects(updatedContext, actor, allies, aliveEnemies);

        } catch (error) {
            this.logger.error(`Unit action processing failed for ${actor.name}`, undefined, error);
            return context;
        }
    }

    /**
     * 选择行动类型
     */
    private selectActionType(
        actor: BattleParticipant,
        enemies: BattleParticipant[],
        allies: BattleParticipant[]
    ): 'attack' | 'skill' | 'defend' {
        // 简化的AI逻辑
        const component = actor.component;
        
        // 检查是否有可用技能
        const availableSkills = component.selfSkill?.filter(skill => 
            skill.cooldown === 0 && component.mp_now >= (skill.mpCost || 0)
        ) || [];

        // 30%概率使用技能（如果有可用技能）
        if (availableSkills.length > 0 && Math.random() < 0.3) {
            return 'skill';
        }

        // 10%概率防御
        if (Math.random() < 0.1) {
            return 'defend';
        }

        // 默认攻击
        return 'attack';
    }

    /**
     * 选择目标
     */
    private selectTargets(
        actor: BattleParticipant,
        enemies: BattleParticipant[],
        allies: BattleParticipant[],
        actionType: string
    ): BattleParticipant[] {
        switch (actionType) {
            case 'attack':
            case 'skill':
                return [this.selectTarget(actor, enemies, TargetSelectionStrategy.RANDOM)];
            case 'defend':
                return [actor]; // 自己
            default:
                return [this.selectTarget(actor, enemies, TargetSelectionStrategy.RANDOM)];
        }
    }

    /**
     * 选择单个目标
     */
    private selectTarget(
        actor: BattleParticipant,
        candidates: BattleParticipant[],
        strategy: TargetSelectionStrategy = TargetSelectionStrategy.RANDOM
    ): BattleParticipant {
        if (candidates.length === 0) {
            throw new Error('No target candidates available');
        }

        if (candidates.length === 1) {
            return candidates[0];
        }

        switch (strategy) {
            case TargetSelectionStrategy.LOWEST_HP:
                return candidates.reduce((lowest, current) => 
                    current.component.hp_now < lowest.component.hp_now ? current : lowest
                );

            case TargetSelectionStrategy.HIGHEST_HP:
                return candidates.reduce((highest, current) => 
                    current.component.hp_now > highest.component.hp_now ? current : highest
                );

            case TargetSelectionStrategy.LOWEST_HP_PERCENT:
                return candidates.reduce((lowest, current) => {
                    const currentPercent = current.component.hp_now / current.component.getAttribute('最大生命值');
                    const lowestPercent = lowest.component.hp_now / lowest.component.getAttribute('最大生命值');
                    return currentPercent < lowestPercent ? current : lowest;
                });

            case TargetSelectionStrategy.RANDOM:
            default:
                return candidates[Math.floor(Math.random() * candidates.length)];
        }
    }

    /**
     * 执行行动
     */
    private async executeAction(
        context: BattleContext,
        actor: BattleParticipant,
        targets: BattleParticipant[],
        actionType: string
    ): Promise<BattleContext> {
        const actionId = this.generateActionId();
        const action: BattleAction = {
            actionId,
            actorId: actor.id,
            type: actionType as any,
            targetIds: targets.map(t => t.id),
            timestamp: Date.now()
        };

        this.logger.debug(`Executing ${actionType} action`, {
            metadata: {
                battleId: context.state.battleId,
                actorId: actor.id,
                targetIds: action.targetIds
            }
        });

        let updatedContext = context;

        switch (actionType) {
            case 'attack':
                updatedContext = await this.executeAttack(updatedContext, actor, targets[0], action);
                break;
            case 'skill':
                updatedContext = await this.executeSkill(updatedContext, actor, targets, action);
                break;
            case 'defend':
                updatedContext = await this.executeDefend(updatedContext, actor, action);
                break;
        }

        return updatedContext;
    }

    /**
     * 执行攻击
     */
    private async executeAttack(
        context: BattleContext,
        attacker: BattleParticipant,
        target: BattleParticipant,
        action: BattleAction
    ): Promise<BattleContext> {
        // 使用原有的攻击逻辑
        const enemies = [target];
        const allies = context.state.homeParticipants.includes(attacker) 
            ? context.state.homeParticipants.filter(p => p.isAlive)
            : context.state.awayParticipants.filter(p => p.isAlive);

        // 调用组件的攻击方法
        const skill = attacker.component.attack(enemies.map(e => e.component), allies.map(a => a.component));

        if (skill) {
            this.logger.debug(`Attack executed: ${attacker.name} -> ${target.name}`, {
                metadata: {
                    battleId: context.state.battleId,
                    skillName: skill.name || 'basic_attack'
                }
            });
        }

        // 检查目标是否死亡
        const updatedContext = await this.updateParticipantStatus(context, target);

        return updatedContext;
    }

    /**
     * 执行技能
     */
    private async executeSkill(
        context: BattleContext,
        caster: BattleParticipant,
        targets: BattleParticipant[],
        action: BattleAction
    ): Promise<BattleContext> {
        const component = caster.component;
        const availableSkills = component.selfSkill?.filter(skill => 
            skill.cooldown === 0 && component.mp_now >= (skill.mpCost || 0)
        ) || [];

        if (availableSkills.length === 0) {
            this.logger.warn(`No available skills for ${caster.name}`);
            return context;
        }

        // 随机选择一个可用技能
        const selectedSkill = availableSkills[Math.floor(Math.random() * availableSkills.length)];
        action.skillId = selectedSkill.skillId;

        this.logger.debug(`Skill executed: ${caster.name} uses ${selectedSkill.skillId}`, {
            metadata: {
                battleId: context.state.battleId,
                skillId: selectedSkill.skillId,
                targetCount: targets.length
            }
        });

        // 使用技能
        const enemies = targets.filter(t => !context.state.homeParticipants.includes(caster) || !context.state.homeParticipants.includes(t));
        const allies = context.state.homeParticipants.includes(caster) 
            ? context.state.homeParticipants.filter(p => p.isAlive)
            : context.state.awayParticipants.filter(p => p.isAlive);

        const skill = component.attack(enemies.map(e => e.component), allies.map(a => a.component));

        // 更新所有目标的状态
        let updatedContext = context;
        for (const target of targets) {
            updatedContext = await this.updateParticipantStatus(updatedContext, target);
        }

        return updatedContext;
    }

    /**
     * 执行防御
     */
    private async executeDefend(
        context: BattleContext,
        defender: BattleParticipant,
        action: BattleAction
    ): Promise<BattleContext> {
        this.logger.debug(`${defender.name} is defending`, {
            metadata: { battleId: context.state.battleId }
        });

        // 防御效果：下回合减少50%伤害（简化实现）
        // 实际应该通过Buff系统实现
        context.temporaryData.set(`defending_${defender.id}`, true);

        return context;
    }

    /**
     * 更新参与者状态
     */
    private async updateParticipantStatus(
        context: BattleContext,
        participant: BattleParticipant
    ): Promise<BattleContext> {
        const isAliveNow = !participant.component.isDie();
        
        if (participant.isAlive !== isAliveNow) {
            const stateManager = new BattleStateManager();
            const updatedContext = stateManager.updateParticipant(context, participant.id, {
                isAlive: isAliveNow
            });

            if (!isAliveNow) {
                this.logger.info(`${participant.name} has been defeated`, {
                    metadata: { 
                        battleId: context.state.battleId,
                        participantId: participant.id
                    }
                });
            }

            return updatedContext;
        }

        return context;
    }

    /**
     * 触发行动后效果
     */
    private async triggerPostActionEffects(
        context: BattleContext,
        actor: BattleParticipant,
        allies: BattleParticipant[],
        enemies: BattleParticipant[]
    ): Promise<BattleContext> {
        // 触发被动技能等
        // 这里简化处理，实际应该有完整的被动技能系统
        
        this.logger.debug(`Triggering post-action effects for ${actor.name}`, {
            metadata: { battleId: context.state.battleId }
        });

        // TODO: 实现被动技能触发逻辑
        return context;
    }

    /**
     * 计算伤害
     */
    calculateDamage(
        attacker: BattleParticipant,
        target: BattleParticipant,
        baseDamage: number,
        damageType: 'physical' | 'magical' | 'true' = 'physical'
    ): DamageCalculationResult {
        let finalDamage = baseDamage;
        const modifiers: Array<{ source: string; type: string; value: number }> = [];

        // 攻击力加成
        const attackPower = damageType === 'physical' 
            ? attacker.component.getAttribute('攻击力')
            : attacker.component.getAttribute('法术强度') || attacker.component.getAttribute('攻击力');
        
        finalDamage += attackPower * 0.1; // 简化的攻击力加成
        modifiers.push({ source: 'attack_power', type: 'additive', value: attackPower * 0.1 });

        // 防御力减免
        if (damageType !== 'true') {
            const defense = damageType === 'physical'
                ? target.component.getAttribute('防御力')
                : target.component.getAttribute('法术防御') || target.component.getAttribute('防御力');
            
            const damageReduction = defense / (defense + 100); // 简化的防御公式
            finalDamage *= (1 - damageReduction);
            modifiers.push({ source: 'defense', type: 'multiplicative', value: damageReduction });
        }

        // 暴击计算
        const criticalChance = attacker.component.getAttribute('暴击率') || 0.05;
        const isCritical = Math.random() < criticalChance;
        if (isCritical) {
            const criticalDamage = attacker.component.getAttribute('暴击伤害') || 1.5;
            finalDamage *= criticalDamage;
            modifiers.push({ source: 'critical', type: 'multiplicative', value: criticalDamage });
        }

        // 格挡计算
        const blockChance = target.component.getAttribute('格挡率') || 0;
        const isBlocked = Math.random() < blockChance;
        if (isBlocked) {
            finalDamage *= 0.5; // 格挡减少50%伤害
            modifiers.push({ source: 'block', type: 'multiplicative', value: 0.5 });
        }

        return {
            baseDamage,
            finalDamage: Math.max(1, Math.floor(finalDamage)), // 至少造成1点伤害
            isCritical,
            isBlocked,
            damageType,
            modifiers
        };
    }

    /**
     * 计算治疗
     */
    calculateHealing(
        healer: BattleParticipant,
        target: BattleParticipant,
        baseHealing: number
    ): HealingCalculationResult {
        let finalHealing = baseHealing;
        const modifiers: Array<{ source: string; type: string; value: number }> = [];

        // 治疗强度加成
        const healPower = healer.component.getAttribute('治疗强度') || healer.component.getAttribute('法术强度') || 0;
        finalHealing += healPower * 0.1;
        modifiers.push({ source: 'heal_power', type: 'additive', value: healPower * 0.1 });

        // 暴击治疗
        const criticalChance = healer.component.getAttribute('暴击率') || 0.05;
        const isCritical = Math.random() < criticalChance;
        if (isCritical) {
            finalHealing *= 1.5;
            modifiers.push({ source: 'critical', type: 'multiplicative', value: 1.5 });
        }

        // 计算实际治疗（不能超过最大生命值）
        const currentHP = target.component.hp_now;
        const maxHP = target.component.getAttribute('最大生命值');
        const actualHealing = Math.min(finalHealing, maxHP - currentHP);

        return {
            baseHealing,
            finalHealing: Math.floor(finalHealing),
            actualHealing: Math.floor(actualHealing),
            isCritical,
            modifiers
        };
    }

    /**
     * 生成行动ID
     */
    private generateActionId(): string {
        return `action_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    }
}
